package com.example.common.util;

import cn.hutool.core.util.ObjectUtil;
import com.example.common.conf.exception.RedisException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * @Author 朱兴邦
 * @CreateDate： 2020/7/28 10:19
 * @Version 1.0
 */
@Slf4j
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class RedisUtil {
    private final JedisPool jedisPool;

    /**
     * 存储字符串键值对
     *
     * @param key
     * @param value
     * @return
     * @author hw
     * @date 2018年12月14日
     */
    public String set(String key, String value) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.set(key, value);
        } catch (Exception e) {
            throw new RedisException(e.getMessage());
        }
    }

    /**
     * 得到对应键的字符串值
     *
     * @param key
     * @return
     * @author hw
     * @date 2018年12月14日
     */
    public String get(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.get(key);
        } catch (Exception e) {
            throw new RedisException(e.getMessage());
        }
    }

    /**
     * 删除字符串键值对
     *
     * @param key
     * @return
     * @author hw
     * @date 2018年12月14日
     */
    public Long del(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.del(key);
        } catch (Exception e) {
            throw new RedisException(e.getMessage());
        }
    }

    /**
     * 存储对象
     *
     * @param key
     * @param value
     * @return
     * @author hw
     * @date 2018年12月14日
     */
    public String setObject(String key, Object value) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.set(key.getBytes(), ObjectUtil.serialize(value));
        } catch (Exception e) {
            throw new RedisException(e.getMessage());
        }
    }

    /**
     * 得到对应键的对象
     *
     * @param key
     * @return
     * @author hw
     * @date 2018年12月14日
     */
    public Object getObject(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            byte[] byteArr = jedis.get(key.getBytes());
            return ObjectUtil.unserialize(byteArr);
        } catch (Exception e) {
            throw new RedisException(e.getMessage());
        }
    }

    /**
     * 设置 大小库，带过期时间
     *
     * @param key
     * @param field
     * @param value
     * @param database
     * @param second
     */
    public void setKfValue(String key, String field, String value, int database, int second) {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.select(database);
            jedis.hset(key, field, value);
            jedis.expire(key, second);
        } catch (Exception e) {
            log.error("setKfValue异常: ", e.getCause());
            throw new RedisException("setKfValue异常");
        }
    }

    /**
     * 获取大小库值
     *
     * @param key
     * @param field
     * @param database
     * @return
     */
    public String getKfValue(String key, String field, int database) {
        String result = null;
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.select(database);
            result = jedis.hget(key, field);
        } catch (Exception e) {
            log.error("getKfValue异常: ", e.getCause());
            throw new RedisException("getKfValue异常");
        }
        return result;
    }

    /**
     * 设置 键值对
     *
     * @param key
     * @param value
     * @param database
     */
    public void setKV(String key, String value, int database) {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.select(database);
            jedis.set(key, value);
        } catch (Exception e) {
            log.error("setKV异常: ", e.getCause());
            throw new RedisException("setKV异常");
        }
    }


    /**
     * 设置 键值对,带过期时间
     *
     * @param key
     * @param value
     * @param database
     * @param expire
     */
    public void setExpireKV(String key, String value, int database, int expire) {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.select(database);
            jedis.set(key, value);
            jedis.expire(key, expire);
        } catch (Exception e) {
            log.error("setExpireKV异常: ", e.getCause());
            throw new RedisException("setExpireKV异常");
        }
    }

    /**
     * 根据key 获取value
     *
     * @param key
     * @param database
     * @return
     */
    public String getKV(String key, int database) {
        String result = null;
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.select(database);
            result = jedis.get(key);
        } catch (Exception e) {
            log.error("getKV异常: ", e.getCause());
            throw new RedisException("getKV异常");
        }
        return result;
    }


    /**
     * 删除某个库里的key
     *
     * @param key
     * @param database
     */
    public void removeKey(String key, int database) {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.select(database);
            jedis.del(key);
        } catch (Exception e) {
            log.error("delKey异常: ", e.getCause());
            throw new RedisException("delKey异常");
        }
    }


    /**
     * 按步数增长
     *
     * @param key
     * @param step
     * @param database
     * @return
     */
    public Long incrByStep(String key, long step, int database) {
        Long result = 0L;
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.select(database);
            result = jedis.incrBy(key, step);
        } catch (Exception e) {
            log.error("incrByStep异常: ", e.getCause());
            throw new RedisException("incrByStep异常");
        }
        return result;
    }

    /**
     * 默认增长一步
     *
     * @Author: jww
     * @CreateDate: 2020/6/16
     * @since : 1.0
     */
    public Long incrOneStep(String key, int database) {
        Long result = 0L;
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.select(database);
            result = jedis.incrBy(key, 1L);
        } catch (Exception e) {
            log.error("incrOneStep异常: ", e.getCause());
            throw new RedisException("incrOneStep异常");
        }
        return result;
    }

    /**
     * 获取jedis
     *
     * @Author: jww
     * @CreateDate: 2020/6/30
     * @since : 1.0
     */
    public Jedis build() {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis;
        } catch (Exception e) {
            log.error("buildJedis异常: ", e.getCause());
            throw new RedisException("buildJedis异常");
        }
    }
}
